package thread.test_3.atomic;

import java.util.concurrent.atomic.AtomicInteger;

public class Test_3 {
    public static void main(String[] args) {
        // 悲观锁：同步synchronized
            // 任何情况下，都认为线程会修改共享数据，所以同一时间只限制一条现场能够访问共享数据
        // 乐观锁：CAS + 自旋
            // 任何情况下都认为线程不会修改共享数据的值，如果发送修改，我们只需要获取最新的值即可
        //使用原子工具类,保证共享数据的原子性操作
        //将卖票案例使用AtomicInteger进行改进
        Ticket_Atom t = new Ticket_Atom();
        Thread t1 = new Thread(t, "窗口1");
        Thread t2 = new Thread(t, "窗口2");
        Thread t3 = new Thread(t, "窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}

class Ticket_Atom implements Runnable {
    //此案例存在问题:
        //1.确实使用AtomicInteger可以保证共享数据的原子性操作
        //2.但是对于该原子数据的操作,调用的方法也必须符合原子性
    //使用AtomicInteger表示共享数据
    private AtomicInteger count = new AtomicInteger(100);

    @Override
    public void run() {
        while (true) {
            //此时将案例进行改进,改进为只调用一次方法
            //由方法内部操作去保证AtomicInteger原子性
            int count = this.count.decrementAndGet();
            //没有加锁的
            if (count < 0) {//共享数据为0结束循环
                break;
            } else {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //decrementAndGet()先执行--再获取值
                System.out.println(Thread.currentThread().getName() + "正在卖票,还剩余" + count + "张票");
            }
        }
    }
}